home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Experimental BBS Explossion 3
/
Experimental BBS Explossion III.iso
/
c
/
bc_pas_1.zip
/
MVOUT.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-12-07
|
10KB
|
304 lines
page 64,131
Title MVOUT -- Pro Audio Spectrum direct I/O
; /*\
;---|*|-------------------------====< MVOUT >====-------------------------
;---|*|
;---|*| This module contains some code for supporting direct I/O to the PAS
;---|*| where the hardware is write only. All calls reference the state
;---|*| table to guarrantee proper I/O values.
;---|*|
;---|*| Media Vision, Inc. Copyright (c) 1991,1992. All Rights Reserved.
;---|*|
; \*/
.xlist
include model.inc
include masm.inc
include state.inc
include common.inc
.list
externADDR MVInitStatePtr ; state table pointer stuff
externADDR mvGetHWVersion ; find the board address...
if MODELSIZE eq 0
.code
else
.data
endif
;
; The following label allows us to calculate an offset for the tables of
; addresses
;
FirstDataByte label byte ; !!!!!! must be the 1st entry in
; ; the data segmment!!!
;
; our first pass flag - set to -1 for first entry, will be zeroed out
;
invmso_first db -1 ; -1 for first pass, to be zeroed out
;
; Hardware Shadowing Table of Registers
;
public shadowregtable
shadowregtable label word
dw SYSSPKRTMR ; 00042h ; System Speaker Timer Address
dw SYSTMRCTLR ; 00043h ; System Timer Control Register
dw SYSSPKRREG ; 00061h ; System Speaker Register
dw JOYSTICK ; 00201h ; Joystick Register
dw LFMADDR ; 00388h ; Left FM Synthesizer Address Register
dw LFMDATA ; 00389h ; Left FM Synthesizer Data Register
dw RFMADDR ; 0038Ah ; Right FM Synthesizer Address Register
dw RFMDATA ; 0038Bh ; Right FM Synthesizer Data Register
dw DFMADDR ;AUXADDR; 00788h ; Dual FM Synthesizer Address Register
dw DFMDATA ;AUXDATA; 00789h ; Dual FM Synthesizer Data Register
dw 0 ; 0078Ah ; reserved for future use
dw 0 ; 0078Bh ; reserved for future use
dw AUDIOMIXR ; 00B88h ; Audio Mixer Control Register
dw INTRCTLRST ; 00B89h ; Interrupt Status Register
dw AUDIOFILT ; 00B8Ah ; Audio Filter Control Register
dw INTRCTLR ; 00B8Bh ; Interrupt Control Register
dw PCMDATA ; 00F88h ; PCM data I/O register
dw 0 ; 00F89h ; reserved for future use
dw CROSSCHANNEL ; 00F8Ah ; Cross Channel
dw 0 ; 00F8Bh ; reserved for future use
dw SAMPLERATE ; 01388h ; Sample Rate Timer Register
dw SAMPLECNT ; 01389h ; Sample Count Register
dw SPKRTMR ; 0138Ah ; Local Speaker Timer Address
dw TMRCTLR ; 0138Bh ; Local Timer Control Register
dw MDIRQVECT ; 01788H ; MIDI IRQ Vector Register
dw MDSYSCTLR ; 01789H ; MIDI System Control Register
dw MDSYSSTAT ; 0178AH ; MIDI IRQ Status Register
dw MDIRQCLR ; 0178BH ; MIDI IRQ Clear Register
dw MDGROUP4 ; 01B88H ; MIDI Group #4 Register
dw MDGROUP5 ; 01B89H ; MIDI Group #5 Register
dw MDGROUP6 ; 01B8AH ; MIDI Group #6 Register
dw MDGROUP7 ; 01B8BH ; MIDI Group #7 Register
SHADOWTABLELEN equ 28 ; 28 entries in the shadow data table
;
; Storage Locations for the data
;
public shadowdatatable
shadowdatatable label word
dw offset _sysspkrtmr ; 00042h ; System Speaker Timer Address
dw offset _systmrctlr ; 00043h ; System Timer Control Register
dw offset _sysspkrreg ; 00061h ; System Speaker Register
dw offset _joystick ; 00201h ; Joystick Register
dw offset _lfmaddr ; 00388h ; Left FM Synthesizer Address Register
dw offset _lfmdata ; 00389h ; Left FM Synthesizer Data Register
dw offset _rfmaddr ; 0038Ah ; Right FM Synthesizer Address Register
dw offset _rfmdata ; 0038Bh ; Right FM Synthesizer Data Register
dw offset _dfmaddr ; 00788h ; Dual FM Synthesizer Address Register
dw offset _dfmdata ; 00789h ; Dual FM Synthesizer Data Register
dw 0 ; 0078Ah ; reserved for future use
dw 0 ; 0078Bh ; reserved for future use
dw offset _audiomixr ; 00B88h ; Audio Mixer Control Register
dw offset _intrctlrst ; 00B89h ; Interrupt Status Register
dw offset _audiofilt ; 00B8Ah ; Audio Filter Control Register
dw offset _intrctlr ; 00B8Bh ; Interrupt Control Register
dw offset _pcmdata ; 00F88h ; PCM data I/O register
dw 0 ; 00F89h ; reserved for future use
dw offset _crosschannel ; 00F8Ah ; Cross Channel
dw 0 ; 00F8Bh ; reserved for future use
dw offset _samplerate ; 01388h ; Sample Rate Timer Register
dw offset _samplecnt ; 01389h ; Sample Count Register
dw offset _spkrtmr ; 0138Ah ; Local Speaker Timer Address
dw offset _tmrctlr ; 0138Bh ; Local Timer Control Register
dw offset _mdirqvect ; 01788H ; MIDI IRQ Vector Register
dw offset _mdsysctlr ; 01789H ; MIDI System Control Register
dw offset _mdsysstat ; 0178AH ; MIDI IRQ Status Register
dw offset _mdirqclr ; 0178BH ; MIDI IRQ Clear Register
dw offset _mdgroup1 ; 01B88H ; MIDI Group #4 Register
dw offset _mdgroup2 ; 01B89H ; MIDI Group #5 Register
dw offset _mdgroup3 ; 01B8AH ; MIDI Group #6 Register
dw offset _mdgroup4 ; 01B8BH ; MIDI Group #7 Register
extrn mvhwShadowPointer :dword
extrn _MVTranslateCode :word ; hardware I/O offset
extrn _MVHWVersionBits :word ; hardware bits
;
;---------------------------========================---------------------------
;---------------------------====< CODE SECTION >====---------------------------
;---------------------------========================---------------------------
;
.code
;
; /*\
;---|*|
;---|*|---------------====< Prototypes >====---------------
;---|*|
;---|*| void MVOut( int, int, int )
;---|*|
;---|*| Output a masked byte directly to the hardware, and return the new value
;---|*|
;---|*| Entry Conditions:
;---|*| wParm1 is the port address
;---|*| wParm2 is the and mask of bits to be written
;---|*| wParm3 is the xor data to be written
;---|*|
;---|*| Exit Conditions:
;---|*| if wParm2 = 0, al = read from hardware, ah = shadowed data
;---|*| if wParm2 = !0, value is written to the hardware & shadow table
; \*/
;
public MVOut
MVOut PROC
push bp
mov bp,sp
;
; this code can only be processed once per loading
;
cmp [invmso_first],-1 ; have we been here?
jnz @F ; yes, don't do this again
mov [invmso_first],0 ; no, so pass by just once
call __initmvout
call MVInitStatePtr ; initialize the state table
@@:
;
; perform the read from the state table, or write to the hardware
;
push es
mov dx,wParm1 ; port address
call _getregisterptr ; get the shadow hardware register ptr
jc mvout_exit ; IO address not found
mov cx,wParm2 ; mask
mov ax,wParm3 ; data
jcxz mvout_read ; read request, just return the data
and al,cl ; merge new and old bits
not cl ; get the other bits
and cl,es:[bx] ; from the shadow state
or al,cl ; and merge them in
xor dx,[_MVTranslateCode] ; xlate the board address
out dx,al ; output to the hardware
mov es:[bx],al ; save the new state
;
mvout_exit:
pop es
pop bp
ret
;
mvout_read:
mov al,es:[bx] ; gets the value from the state table
jmp short mvout_exit
MVOut endp
;
; /*\
;---|*|---------------====< __initmvout() >====---------------
;---|*|
;---|*| Initializes this body of code. It will try to find the int 2F DOS
;---|*| interface to the MVPROAS device. Once found, the new state table
;---|*| pointer will be loaded.
;---|*|
;---|*| Entry Conditions:
;---|*| None
;---|*|
;---|*| Exit Conditions:
;---|*| DX:AX point to the state table
; \*/
__initmvout proc near
push es
push di
mov ax,ds
mov es,ax
;
; adjust the shadow data table offsets to the correct linked offset
;
mov cx,SHADOWTABLELEN ; table length...
lea bx,FirstDataByte ; the compiled offsets must be adjusted
lea di,shadowdatatable ; DI points to the table
;
@@:
add es:[di],bx ; move the offsets in the table
inc di
inc di
loop @B
cmp [_MVHWVersionBits],-1 ; already found?
jnz inmv_done ; yes, continue on..
mov ax,USE_ACTIVE_ADDR ; defaults to the original address
push ax
call mvGetHWVersion ; find the board address...
add sp,2
;
inmv_done:
pop di
pop es
ret
__initmvout endp
;
;---------------------====< _getregisterptr >====---------------
;
; Get a pointer to the state table
;
; Entry Conditions:
; DX holds the port address
;
; Exit Conditions:
; ES:BX holds the pointer, no other registers modified
;
_getregisterptr proc near
push di ; no toucha dees...
push cx
mov cx,ds
mov es,cx
lea di,shadowregtable ; look in the register table
mov cx,SHADOWTABLELEN
xchg ax,dx ; ax holds the port address
cld
repne scasw
xchg ax,dx ; restore 'em...
stc ; just in case we bomb out
jne @F ; no match, bomb out...
if MODELSIZE eq 0
assume es:@code ; tiny (.com) model is same as code
else
assume es:@data ; all other has a data segment
endif
sub di,offset shadowregtable+2 ; create an offset into the table
mov bx,es:[shadowdatatable+di] ; bx = the offset from the 1st ptr
mov di,es:[shadowdatatable+0] ; grab the first ptr
sub bx,di ; bx holds a zero based offset
les di,mvhwShadowPointer ; get the true state table pointer
add bx,di ; bx now points into the true table
assume es:nothing
clc ; was found, indicate so...
;
@@:
pop cx
pop di
ret
_getregisterptr endp
; /*\
;---|*| end of MVOut
; \*/
end